package org.redhat.auth.security.util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import org.redhat.auth.security.user.UserDetailInfo;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;

/**
 * 登录用户信息封装类，通过此类可直接调用到当前登录用户的各种信息
 * 
 * @author lingen.liu
 * 
 */
public class AuthUserUtil {

	public static String getLoginUserName() {
		if(SecurityContextHolder.getContext().getAuthentication()==null)return null;
		Object o = SecurityContextHolder.getContext().getAuthentication()
				.getPrincipal();
		if (o != null && o instanceof UserDetails) {
			UserDetails userDetail = (UserDetails) o;
			String username = userDetail.getUsername();
			return username;
		}
		return null;
	}
	

	/**
	 * 返回当前登录用户
	 * 
	 * @return
	 */
	public static UserDetailInfo getLoginUser() {
		Object o = SecurityContextHolder.getContext().getAuthentication()
				.getPrincipal();
		if (o != null && o instanceof UserDetails) {
			UserDetails userDetail = (UserDetails) o;
			String username = userDetail.getUsername();

			UserDetailInfo user = UserCacheUtil.getUserInfo(username);

			return user;
		}
		return null;
	}

	/**
	 * 此方法获取登录中扩展属性的值
	 * 
	 * @param property
	 * @return
	 */
	public static Object getUserProperty(String property) {
		Object login = AuthLoginParamUtil.getUserParam(getLoginUserName());
		Class c = login.getClass();
		String methodName = "get" + property.substring(0, 1).toUpperCase()
				+ property.substring(1);
		Object result = null;
		try {
			Method method = c.getMethod(methodName, null);
			result = method.invoke(login, null);
		} catch (SecurityException e) {
			result = null;
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			result = null;
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			result = null;
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			result = null;
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			result = null;
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * 此方法获取userdetail中非扩展属性的值
	 * 
	 * @param property
	 * @return
	 */
	public static Object getProperty(String property) {
		Object o = SecurityContextHolder.getContext().getAuthentication()
				.getPrincipal();
		if (o instanceof UserDetails == false) {
			return null;
		}
		UserDetails userDetail = (UserDetails) o;

		Class c = userDetail.getClass();
		String methodName = "get" + property.substring(0, 1).toUpperCase()
				+ property.substring(1);
		Object result = null;
		try {
			Method method = c.getMethod(methodName, null);
			result = method.invoke(userDetail, null);
		} catch (SecurityException e) {
			result = null;
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			result = null;
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			result = null;
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			result = null;
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			result = null;
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 返回当前登录用户所具有的所有的权限,返回一个String类型的ArrayList
	 * 
	 * @return
	 */
	public static ArrayList<String> getRoles() {
		ArrayList roles = new ArrayList();
		UserDetailInfo user = (UserDetailInfo) SecurityContextHolder
				.getContext().getAuthentication().getPrincipal();
		Collection<GrantedAuthority> cas = user.getAuthorities();
		for (GrantedAuthority ca : cas) {
			String role = ca.getAuthority();
			roles.add(role);
		}
		return roles;
	}

	/**
	 * 当前是否有用户登录到系统
	 * 
	 * @return
	 */
	public boolean isUserLogin() {
		Object o = SecurityContextHolder.getContext().getAuthentication()
				.getPrincipal();
		if (o != null && o instanceof UserDetailInfo)
			return true;
		return false;
	}
}
